package services

import (
	"encoding/json"
	"errors"
	"lingc/models"
	"lingc/utils"
	"log"
	"os"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// SysLangDetailService 提供账号登录校验的服务
type SysLangDetailService struct {
	DB *gorm.DB
}

// 缓存时间
const configCahceTime = "lang_cahce_time"

// NewSysLangDetailService 创建一个新的 SysLangDetailService 实例
func NewSysLangDetailService(db *gorm.DB) *SysLangDetailService {
	return &SysLangDetailService{DB: db}
}

//表单业务

/**
 * @Description: 分页获取列表
 * @param where
 * @param page
 * @param pageSize
 * @return []*models.SysLangDetail
 * @return int
 * @return int64
 * @return error
 */
func (s *SysLangDetailService) PageSysLangDetailList(where string, page, pageSize int) ([]*models.SysLangDetailList, int, int64, error) {
	var lists []*models.SysLangDetail
	var total int64

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 获取总记录数
	if err := s.DB.Model(&models.SysLangDetail{}).Where(where).Count(&total).Error; err != nil {
		return nil, 1, 0, err
	}

	// 获取分页数据
	if err := s.DB.Where(where).Offset(offset).Limit(pageSize).Order("id DESC").Find(&lists).Error; err != nil {
		return nil, 1, 0, err
	}
	var list []*models.SysLangDetailList
	list = []*models.SysLangDetailList{}
	for _, data := range lists {

		list = append(list, &models.SysLangDetailList{
			ID:     data.ID,
			LangID: data.LangID,
			ItemID: data.ItemID,
			Text:   data.Text,
			AppID:  data.AppID,
		})
	}

	return list, page, total, nil
}

func (s *SysLangDetailService) SysLangDetailList(item_id uint) ([]*models.SysLangDetailList, error) {
	var lists []*models.SysLangDetail
	var list []*models.SysLangDetailList
	list = []*models.SysLangDetailList{}
	// 获取分页数据
	if err := s.DB.Where("item_id = ?", item_id).Find(&lists).Error; err != nil {
		return list, err
	}
	for _, data := range lists {

		list = append(list, &models.SysLangDetailList{
			ID:     data.ID,
			LangID: data.LangID,
			ItemID: data.ItemID,
			Text:   data.Text,
			AppID:  data.AppID,
		})
	}

	return list, nil
}

/**
 * @Description: 创建新
 * @param username
 * @param password
 * @param realname
 * @param avatar
 * @param status
 * @return *models.SysLangDetailCreate
 * @return error
 */
func (s *SysLangDetailService) CreateSysLangDetail(data *models.SysLangDetailCreate) (*models.SysLangDetailCreate, error) {

	/*
		ID     uint   `json:"id"`
		LangID uint   `json:"lang_id"`
		ItemID uint   `json:"item_id"`
		Text   string `json:"text"`
		AppID  int    `json:"app_id"`
	*/
	addData := &models.SysLangDetail{
		LangID: data.LangID,
		ItemID: data.ItemID,
		Text:   data.Text,
		AppID:  data.AppID,
	}
	// 保存到数据库
	if err := s.DB.Create(addData).Error; err != nil {
		return nil, err
	}
	return data, nil
}

/**
 * @Description: 创建新
 * @param username
 * @param password
 * @param realname
 * @param avatar
 * @param status
 * @return *models.SysLangDetailCreate
 * @return error
 */
func (s *SysLangDetailService) CreateSysLangDetails(data *models.SysLangItem, detail string) ([]uint, error) {

	/*
		ID     uint   `json:"id"`
		LangID uint   `json:"lang_id"`
		ItemID uint   `json:"item_id"`
		Text   string `json:"text"`
		AppID  int    `json:"app_id"`
	*/
	where := "status = ?"
	var list []*models.SysLang
	// 获取分页数据
	if err := s.DB.Where(where, 1).Find(&list).Error; err != nil {
		return []uint{}, err
	}
	detailData := []*models.SysLangDetailUpdate{}
	json.Unmarshal([]byte(detail), &detailData)

	mapDetail := map[string]string{}

	for _, detail := range detailData {
		key := strconv.Itoa(int(detail.LangID)) + "_" + strconv.Itoa(int(data.ID))
		mapDetail[key] = detail.Text
	}
	ids := []uint{}
	for _, lang := range list {
		key := strconv.Itoa(int(lang.ID)) + "_" + strconv.Itoa(int(data.ID))
		addData := &models.SysLangDetail{
			LangID: lang.ID,
			ItemID: data.ID,
			Text:   mapDetail[key],
			AppID:  data.AppID,
		}
		// 保存到数据库
		if err := s.DB.Create(addData).Error; err != nil {
			return []uint{}, err
		}
		ids = append(ids, addData.ID)
	}
	return ids, nil
}

/**
 * @Description: 更新信息
 * @param data
 * @return error
 */
func (s *SysLangDetailService) UpdateSysLangDetails(detail string) ([]uint, error) {

	ids := []uint{}
	detailData := []*models.SysLangDetailUpdate{}
	json.Unmarshal([]byte(detail), &detailData)
	mapDetail := map[string]string{}

	for _, detail := range detailData {
		ids = append(ids, detail.ID)
		key := strconv.Itoa(int(detail.LangID)) + "_" + strconv.Itoa(int(detail.ItemID))
		mapDetail[key] = detail.Text
		// 检查名是否已存在
		var existingData models.SysLangDetail
		if err := s.DB.Where("lang_id = ?", detail.LangID).Where("item_id = ?", detail.ItemID).First(&existingData).Error; err != nil {
			return nil, errors.New("数据不存在")
		}
		if detail.Text != existingData.Text {
			// 检查名是否已存在
			existingData.Text = detail.Text
			err := s.DB.Save(existingData).Error
			if err != nil {
				return nil, errors.New("更新失败")
			}
		}
	}
	return ids, nil
	/*
		ID     uint   `json:"id"`
		LangID uint   `json:"lang_id"`
		ItemID uint   `json:"item_id"`
		Text   string `json:"text"`
		AppID  int    `json:"app_id"`
	*/

}

/**
 * @Description: 更新信息
 * @param data
 * @return error
 */
func (s *SysLangDetailService) UpdateSysLangDetail(data *models.SysLangDetailUpdate) (*models.SysLangDetailUpdate, error) {

	// 检查名是否已存在
	var existingData models.SysLangDetail
	if err := s.DB.Where("id = ?", data.ID).First(&existingData).Error; err != nil {
		return nil, errors.New("数据不存在")
	}
	/*
	   Title     string `json:"title"`
	   Name      string `json:"name"`
	   Code      string `json:"code"`
	   LangCode  string `json:"lang_code"`
	   IsDefault uint8  `json:"is_default"`
	   Status    uint8  `json:"status"`
	   AppID     int    `json:"app_id"`
	*/
	existingData.Text = data.Text
	err := s.DB.Save(existingData).Error
	if err != nil {
		return nil, err
	}
	return data, nil
}

/**
 * @Description: 删除
 * @param id
 * @return error
 */
func (s *SysLangDetailService) DeleteSysLangDetail(id uint) error {
	var data models.SysLangDetail
	if err := s.DB.Where("item_id = ?", id).First(&data).Error; err != nil {
		return errors.New("数据不存在")
	}
	return s.DB.Delete(&data).Error
}

/**
 * @Description: 批量删除
 * @param id
 * @return error
 */
func (s *SysLangDetailService) DeleteSysLangDetails(ids []string) error {
	for _, id := range ids {
		var data models.SysLangDetail
		err := s.DB.Where("item_id = ?", id).Delete(&data).Error
		if err != nil {
			return errors.New("删除失败")
		}
	}
	return nil
}

// 获取缓存时间
func (s *SysLangDetailService) GetCahceConfigTime(c *gin.Context) int64 {

	dataJson := utils.GetRedis(configCahceTime)
	if dataJson != "" {
		time := utils.StrToInt64(dataJson)
		return time
	}
	return time.Now().Unix()
}

// 设置缓存时间
func (s *SysLangDetailService) SetCahceConfigTime(c *gin.Context) error {

	time := time.Now().Unix()
	err := utils.SetRedis(configCahceTime, time, 0)
	if err != nil {
		return errors.New("设置缓存时间失败")
	}
	return nil
}

// GetSysLangList 获取语言列表
func (s *SysLangDetailService) GetSysLangList(is_update bool) (string, error) {
	fileCache, err := utils.NewFileCache("./cache")
	if err != nil {
		//创建文件夹
		if err := os.MkdirAll("./cache", os.ModePerm); err != nil {
			return "", errors.New("failed to create cache directory")
		}
	}
	if !is_update {
		log.Printf("从缓存中获取语言列表")
		if data, err := fileCache.GetFile("lang_list.json"); err == nil {
			log.Printf("成功从缓存中获取语言列表%v", data)
			return string(data), nil
		}
	}
	// 获取语言列表
	lang_list, err := NewSysLangService(utils.MysqlClient).GetLangList()
	if err != nil {
		return "", errors.New("failed to fetch language list")
	}

	// 构建语言映射
	lang_map := make(map[string]string)
	lang_map_list := make(map[string]interface{})
	for _, lang := range lang_list {
		key := strconv.Itoa(int(lang.ID))
		lang_map[key] = lang.Code
		lang_map_list[lang.Code] = make(map[string]string)
	}

	// 获取语言项列表
	lang_item_list, err := NewSysLangItemService(utils.MysqlClient).GetLangItemList()
	if err != nil {
		return "", errors.New("failed to fetch language item list")
	}

	// 获取详细数据
	var lists []*models.SysLangDetail
	err = s.DB.Where("1=1").Find(&lists).Error
	if err != nil {
		return "", errors.New("failed to fetch language detail list")
	}
	log.Printf("lang_map---%v", lang_map)
	log.Printf("lang_item_list---%v", lang_item_list)
	// 遍历详细数据并填充映射
	for _, data := range lists {
		log.Printf("lang_item_data%v", data)
		langIDKey := strconv.Itoa(int(data.LangID))
		langCode, exists := lang_map[langIDKey]
		if !exists {
			continue // 跳过无效的语言映射
		}

		itemKey, exists := lang_item_list[data.ItemID]
		if !exists {
			continue // 跳过无效的语言项映射
		}

		// 确保 lang_map_list[langCode] 存在且为 map[string]string 类型
		if _, exists := lang_map_list[langCode]; !exists {
			lang_map_list[langCode] = make(map[string]string)
		}
		log.Printf("lang_item：%s,%v", itemKey, data.Text)
		// 填充数据
		lang_map_list[langCode].(map[string]string)[itemKey] = data.Text
	}

	// 序列化为 JSON
	jsonData, err := json.Marshal(lang_map_list)
	if err != nil {
		return "", errors.New("failed to marshal data")
	}
	if err := fileCache.StoreCache("lang_list.json", jsonData); err != nil {
		return "", errors.New("failed to save data")
	}
	return string(jsonData), nil
}
